home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
AmigActive 10
/
AACD 10.iso
/
AACD
/
System
/
SafeSwitch
/
SafeSwitch.s
< prev
next >
Wrap
Text File
|
2000-05-26
|
13KB
|
360 lines
include "exec/memory.i"
include "exec/semaphores.i"
include "equs" ; not included
include "start.i"
STRUCTURE mymsg,LN_SIZE
APTR ReplyPort
UWORD Length
LONG Reg1 ; d0
LONG Reg2 ; a0
LONG Reg3 ; a1
LONG Reg4 ; a6
APTR FuncPtr
LABEL mymsg_SIZEOF
init move.l 4,a6
lea intuiname,a1 ; open intuition
move.l #37,d0
jsr _LVOOpenLibrary(a6)
move.l d0,d7 ; d7 = intuibase
beq cleanup
jsr _LVOCreateMsgPort(a6)
move.l d0,msgport
beq cleanup
move.l d0,a0
move.b MP_SIGBIT(a0),d1
move.l #0,d0
bset d1,d0
move.l d0,d6 ; d6 = portsig
lea semaphore,a0 ; initialize semaphore
jsr _LVOInitSemaphore(a6)
lea functab,a5 ; patch the routines
setfuncloop move.l d7,a1 ; library base
move.l (a5)+,a0 ; LVO
move.l (a5)+,d0 ; our routine
jsr _LVOSetFunction(a6)
move.l (a5)+,a0 ; where to put oldFunc
move.l d0,(a0)
tst.l (a5) ; last routine to be replaced?
bne setfuncloop
sigloop move.l d6,d0 ; wait for portsig
bset #SIGBREAKB_CTRL_C,d0 ; and Ctrl+C
jsr _LVOWait(a6)
btst #SIGBREAKB_CTRL_C,d0
bne goaway
lea semaphore,a0
jsr _LVOObtainSemaphore(a6)
msgloop move.l msgport,a0
jsr _LVOGetMsg(a6)
tst.l d0
beq endmsgloop
move.l d0,a2
lea Reg1(a2),a3
movem.l (a3)+,d0/a0-a1/a6 ; ScreenDepth() needs 3 args + a6,
move.l FuncPtr(a2),a3 ; others 0 or 1 args + a6
jsr (a3)
move.l 4,a6
move.l a2,a1
jsr _LVOFreeVec(a6)
bra msgloop
endmsgloop lea semaphore,a0
jsr _LVOReleaseSemaphore(a6)
bra sigloop
goaway lea functab,a5
10$ move.l d7,a1 ; put the old routines back
move.l (a5)+,a0 ; LVO
tst.l (a5)+ ; skip our routine
move.l (a5)+,a2 ; old routine
move.l (a2),d0
jsr _LVOSetFunction(a6)
tst.l (a5) ; last routine?
bne 10$
cleanup move.l msgport,d2 ; delete msgport
beq 30$
10$ move.l d2,a0 ; get all messages and free them
jsr _LVOGetMsg(a6) ; (even though we aren't supposed
tst.l d0 ; to be quitted =)
beq 20$
move.l d0,a1
jsr _LVOFreeVec(a6)
bra 10$
20$ move.l d2,a0
jsr _LVODeleteMsgPort(a6)
30$ move.l d7,d0 ; close intuition
beq 40$
move.l d0,a1
jsr _LVOCloseLibrary(a6)
40$ move.l #0,d0
rts
;/// "replacement functions"
; ScreenToFront()
func1 movem.l d0/a0-a1/a6,-(a7) ; preserve registers
move.l 4,a6
lea semaphore,a0
jsr _LVOAttemptSemaphore(a6)
tst.l d0 ; did we get the semaphore?
beq 20$ ; no -> switch screens later, return now
movem.l (a7)+,d0/a0-a1/a6 ; yes -> restore registers
pea 10$ ; where to go after oldFunc()
move.l of1,-(a7) ; go to oldFunc() after rts
rts
10$ movem.l a0/a6,-(a7) ; release the semaphore after oldFunc()
move.l 4,a6
lea semaphore,a0
jsr _LVOReleaseSemaphore(a6)
movem.l (a7)+,a0/a6
rts ; and return to the calling program
20$ move.l #mymsg_SIZEOF,d0 ; send message: switch screens sometime
move.l #MEMF_CLEAR ! MEMF_PUBLIC,d1
jsr _LVOAllocVec(a6) ; allocate memory for the message
tst.l d0
beq 30$
move.l d0,a1 ; initialize the message
move.w #mymsg_SIZEOF,Length(a1)
move.l of1,FuncPtr(a1) ; call this function
move.l (a7),Reg1(a1) ; with these parameters
move.l 4(a7),Reg2(a1)
move.l 8(a7),Reg3(a1)
move.l 12(a7),Reg4(a1)
move.l msgport,a0
jsr _LVOPutMsg(a6) ; whenever :)
30$ movem.l (a7)+,d0/a0-a1/a6 ; restore registers
rts ; return to the calling program
; ScreenToBack() - same as ScreenToFront()
func2 movem.l d0/a0-a1/a6,-(a7)
move.l 4,a6
lea semaphore,a0
jsr _LVOAttemptSemaphore(a6)
tst.l d0
beq 20$
movem.l (a7)+,d0/a0-a1/a6
pea 10$
move.l of2,-(a7)
rts
10$ movem.l a0/a6,-(a7)
move.l 4,a6
lea semaphore,a0
jsr _LVOReleaseSemaphore(a6)
movem.l (a7)+,a0/a6
rts
20$ move.l #mymsg_SIZEOF,d0
move.l #MEMF_CLEAR ! MEMF_PUBLIC,d1
jsr _LVOAllocVec(a6)
tst.l d0
beq 30$
move.l d0,a1
move.w #mymsg_SIZEOF,Length(a1)
move.l of2,FuncPtr(a1)
move.l (a7),Reg1(a1)
move.l 4(a7),Reg2(a1)
move.l 8(a7),Reg3(a1)
move.l 12(a7),Reg4(a1)
move.l msgport,a0
jsr _LVOPutMsg(a6)
30$ movem.l (a7)+,d0/a0-a1/a6
rts
; WBenchToFront() - same as ScreenToFront(), just sets a TRUE return code
; if AttemptSemaphore() failed (see second last line)
func3 movem.l d0/a0-a1/a6,-(a7)
move.l 4,a6
lea semaphore,a0
jsr _LVOAttemptSemaphore(a6)
tst.l d0
beq 20$
movem.l (a7)+,d0/a0-a1/a6
pea 10$
move.l of3,-(a7)
rts
10$ movem.l a0/a6,-(a7)
move.l 4,a6
lea semaphore,a0
jsr _LVOReleaseSemaphore(a6)
movem.l (a7)+,a0/a6
rts
20$ move.l #mymsg_SIZEOF,d0
move.l #MEMF_CLEAR ! MEMF_PUBLIC,d1
jsr _LVOAllocVec(a6)
tst.l d0
beq 30$
move.l d0,a1
move.w #mymsg_SIZEOF,Length(a1)
move.l of3,FuncPtr(a1)
move.l (a7),Reg1(a1)
move.l 4(a7),Reg2(a1)
move.l 8(a7),Reg3(a1)
move.l 12(a7),Reg4(a1)
move.l msgport,a0
jsr _LVOPutMsg(a6)
30$ movem.l (a7)+,d0/a0-a1/a6
move.l #1,d0 ; set return value: true
rts
; WBenchToBack() - same as WBenchToFront()
func4 movem.l d0/a0-a1/a6,-(a7)
move.l 4,a6
lea semaphore,a0
jsr _LVOAttemptSemaphore(a6)
tst.l d0
beq 20$
movem.l (a7)+,d0/a0-a1/a6
pea 10$
move.l of4,-(a7)
rts
10$ movem.l a0/a6,-(a7)
move.l 4,a6
lea semaphore,a0
jsr _LVOReleaseSemaphore(a6)
movem.l (a7)+,a0/a6
rts
20$ move.l #mymsg_SIZEOF,d0
move.l #MEMF_CLEAR ! MEMF_PUBLIC,d1
jsr _LVOAllocVec(a6)
tst.l d0
beq 30$
move.l d0,a1
move.w #mymsg_SIZEOF,Length(a1)
move.l of4,FuncPtr(a1)
move.l (a7),Reg1(a1)
move.l 4(a7),Reg2(a1)
move.l 8(a7),Reg3(a1)
move.l 12(a7),Reg4(a1)
move.l msgport,a0
jsr _LVOPutMsg(a6)
30$ movem.l (a7)+,d0/a0-a1/a6
move.l #1,d0
rts
; ScreenDepth() - same as ScreenToFront()
func5 movem.l d0/a0-a1/a6,-(a7)
move.l 4,a6
lea semaphore,a0
jsr _LVOAttemptSemaphore(a6)
tst.l d0
beq 20$
movem.l (a7)+,d0/a0-a1/a6
pea 10$
move.l of5,-(a7)
rts
10$ movem.l a0/a6,-(a7)
move.l 4,a6
lea semaphore,a0
jsr _LVOReleaseSemaphore(a6)
movem.l (a7)+,a0/a6
rts
20$ move.l #mymsg_SIZEOF,d0
move.l #MEMF_CLEAR ! MEMF_PUBLIC,d1
jsr _LVOAllocVec(a6)
tst.l d0
beq 30$
move.l d0,a1
move.w #mymsg_SIZEOF,Length(a1)
move.l of5,FuncPtr(a1)
move.l (a7),Reg1(a1)
move.l 4(a7),Reg2(a1)
move.l 8(a7),Reg3(a1)
move.l 12(a7),Reg4(a1)
move.l msgport,a0
jsr _LVOPutMsg(a6)
30$ movem.l (a7)+,d0/a0-a1/a6
rts
; OpenWindow()
func6 movem.l a0/a6,-(a7) ; preserve the registers we change
move.l 4,a6
lea semaphore,a0 ; ObtainSemaphore() preserves all registers!
jsr _LVOObtainSemaphore(a6)
movem.l (a7)+,a0/a6
pea 10$ ; where to go after oldFunc()
move.l of6,-(a7) ; go to oldFunc() after rts
rts
10$ movem.l a0/a6,-(a7) ; release the semaphore after oldFunc()
move.l 4,a6
lea semaphore,a0
jsr _LVOReleaseSemaphore(a6)
movem.l (a7)+,a0/a6
rts ; and return to the calling program
; OpenWindowTagList() - same as OpenWindow()
func7 movem.l a0/a6,-(a7)
move.l 4,a6
lea semaphore,a0
jsr _LVOObtainSemaphore(a6)
movem.l (a7)+,a0/a6
pea 10$
move.l of7,-(a7)
rts
10$ movem.l a0/a6,-(a7)
move.l 4,a6
lea semaphore,a0
jsr _LVOReleaseSemaphore(a6)
movem.l (a7)+,a0/a6
rts
;///
intuiname dc.b 'intuition.library',0
verstr dc.b '$VER: SafeSwitch 1.0 (27 May 2000)',0
ds.l 0
functab dc.l _LVOScreenToFront, func1, of1
dc.l _LVOScreenToBack, func2, of2
dc.l _LVOWBenchToFront, func3, of3
dc.l _LVOWBenchToBack, func4, of4
dc.l _LVOScreenDepth, func5, of5
dc.l _LVOOpenWindow, func6, of6
dc.l _LVOOpenWindowTagList, func7, of7
dc.l 0
section variables,data
of1 dc.l 0 ; pointers to the old functions
of2 dc.l 0
of3 dc.l 0
of4 dc.l 0
of5 dc.l 0
of6 dc.l 0
of7 dc.l 0
msgport dc.l 0
semaphore ds.b SS_SIZE